package com.lianzhihui.romeex.net;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.blankj.utilcode.util.ToastUtils;
import com.lianzhihui.romeex.MyApplication;
import com.lianzhihui.romeex.R;
import com.lianzhihui.romeex.config.DataManager;
import com.lianzhihui.romeex.ogdb.Constants;
import com.lianzhihui.romeex.ui.base.ActivityManager;
import com.lianzhihui.romeex.utils.AESCrypt;
import com.lianzhihui.romeex.utils.BitcoinjUtils;
import com.lianzhihui.romeex.utils.GsonUtil;
import com.lianzhihui.romeex.utils.LogUtil;
import com.lianzhihui.romeex.utils.NetUtil;
import com.lianzhihui.romeex.utils.SystemUtils;
import com.zhouyou.http.EasyHttp;
import com.zhouyou.http.body.ProgressResponseCallBack;
import com.zhouyou.http.cache.converter.SerializableDiskConverter;
import com.zhouyou.http.callback.CallBack;
import com.zhouyou.http.exception.ApiException;
import com.zhouyou.http.model.HttpHeaders;
import com.zhouyou.http.model.HttpParams;

import org.json.JSONObject;

import java.io.File;
import java.math.BigInteger;
import java.net.Proxy;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.LinkedHashMap;

import io.reactivex.disposables.Disposable;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.RequestBody;

import static com.blankj.utilcode.util.ActivityUtils.startActivity;

public class HttpManager {
    private static final String LOG_TAG = "HttpManager";
    private static String IMEI = "";
    private String baseUrl;
    private final HttpManagerCallback httpManagerCallback;
    private Context context;

    public HttpManager(HttpManagerCallback httpManagerCallback) {
        this.httpManagerCallback = httpManagerCallback;
    }

    public HttpManager(Context context, HttpManagerCallback httpManagerCallback) {
        this.context = context;
        this.httpManagerCallback = httpManagerCallback;
    }

    /************************************
     * @作者 zhaofeng
     * @描述 初始化网络配置
     * @日期 2019/7/17 14:48
     ************************************/

    public static void initBaseConfig() {
        //设置请求参数
        HttpParams params = new HttpParams();
        EasyHttp.getInstance()
//                .debug(LOG_TAG, MyApplication.isDebug())
                .setReadTimeOut(15 * 1000)
                .setWriteTimeOut(15 * 1000)
                .setConnectTimeout(60 * 1000)
                .setRetryCount(0)//默认网络不好自动重试2次
                .setRetryDelay(5000)//每次延时500ms重试
                .setRetryIncreaseDelay(5000)//每次延时叠加500ms
                .setBaseUrl(APIConstant.getBASE_URL())
                .setCacheDiskConverter(new SerializableDiskConverter())//默认缓存使用序列化转化
                .setCacheMaxSize(50 * 1024 * 1024)//设置缓存大小为50M
                .setCacheVersion(1)//缓存版本为1
//                .setCacheMode(CacheMode.DEFAULT) //可以全局统一设置缓存时间,默认永不过)
//                .setHostnameVerifier(new UnSafeHostnameVerifier(Constant.BASE_URL_TEST))//全局访问规则
                .setCertificates()//信任所有证书
                .setOkproxy(Proxy.NO_PROXY)
                //.addConverterFactory(GsonConverterFactory.create(new Gson()))//本框架没有采用Retrofit的Gson转化，所以不用配置
//                .addCommonHeaders(headers)//设置全局公共头
                .addCommonParams(params)//设置全局公共参数
                .addInterceptor(new CustomSignInterceptor());//添加参数签名拦截器
    }

    public HttpHeaders getHeaders() {
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
//        headers.put("userAddress", "1EKtZL7k7SSsRbGsywzwM4tgrjmR8SrU8F");
        if (DataManager.getUserInfo() != null) {
            headers.put("userAddress", DataManager.getUserInfo().getAddress());
            headers.put("pubKeyAsStr", DataManager.getUserInfo().getCompressedPubkey());
        }
//        if (DataManager.getLocation() != null) {
//            headers.put("posation", DataManager.getLocation().getLatitude() + "," + DataManager.getLocation().getLongitude());
//        }
        headers.put("Content-Type", "application/json; charset=utf8");
        headers.put("Accept", "application/json");
//        headers.put("language", DataManager.getLangType());
//        headers.put("moneytype", DataManager.getMoneyType());
        headers.put("os", "android");
        IMEI = SystemUtils.getAndroidId(context);
        headers.put("imei", IMEI);
        headers.put("versionName", SystemUtils.getAppVersionName(context));
        headers.put("timestamp", String.valueOf(System.currentTimeMillis()));
        return headers;
    }

    /**
     * 报错则重启应用
     *
     * @param context
     */
    public void restartApplication(Context context) {
        ActivityManager.getInstance().finishAllActivity();
        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    /**
     * 自定义header post请求
     *
     * @param url
     * @param params
     * @param httpHeaders
     */
    public synchronized Disposable post(final String url, HttpParams params, HttpHeaders httpHeaders) {
        final CustomPostRequest customPostRequest = new CustomPostRequest(url);
        JSONObject jsonObject = new JSONObject(params.urlParamsMap);
        if (DataManager.getUserInfo() == null) {
            restartApplication(context);
            return null;
        }
        if (DataManager.getUserInfo() == null) {
            restartApplication(context);
            return null;
        }
        String privateKey = null;
        try {
            privateKey = AESCrypt.decrypt(DataManager.getUserInfo().getSaftyCode(), DataManager.getUserInfo().getCompressedPrivkey());
        } catch (GeneralSecurityException e) {
            restartApplication(context);
        }

        String originalBody = jsonObject.toString() + Constants.getSTAMP_KEY() + httpHeaders.get("timestamp");
        String bitcoinJBody = BitcoinjUtils.signMsg(originalBody, privateKey).replace(" ", "").trim();
        httpHeaders.put("signAsStr", bitcoinJBody);

        customPostRequest.headers(httpHeaders);
        LogUtil.info(LOG_TAG, httpHeaders.toJSONString());
//        boolean bitcoinPub = BitcoinjUtils.verifyMessage(originalBody, bitcoinJBody,DataManager.getUserInfo().getCompressedPubkey());
//        Log.d(LOG_TAG,"私钥:"+privateKey+"公钥:"+DataManager.getUserInfo().getCompressedPubkey()+"加密前:"+originalBody+"加密后:"+bitcoinJBody+"是否验证成功："+bitcoinPub);
        RequestBody requestBody = FormBody.create(MediaType.parse("application/json"), jsonObject.toString());
        customPostRequest.requestBody(requestBody);
        if (baseUrl != null) {
            customPostRequest.baseUrl(baseUrl);
        } else {
            customPostRequest.baseUrl(APIConstant.getBASE_URL());
        }
        //此框架类型被擦除
        return customPostRequest.execute(new CallBack<String>() {

            @Override
            public void onStart() {
                httpManagerCallback.onStart();
            }

            @Override
            public void onCompleted() {
                httpManagerCallback.onCompleted();
//                httpManagerCallback.onRes();
            }

            @Override
            public void onError(ApiException e) {
                httpManagerCallback.onResp();
                LogUtil.info("wase", e.getMessage() + "<<ApiException");
                if (context != null) {
//                    Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                httpManagerCallback.onError(e);
            }

            @Override
            public void onSuccess(String str) {
                httpManagerCallback.onResp();
                LogUtil.info("wase", str + "<<http");
                if (str == null || "".equals(str)) {
                    ApiException apiException = new ApiException(new Throwable("返回数据为null"), -100);
//                    Toast.makeText(context,apiException.getMessage(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    return;
                }
                ResultData baseData = GsonUtil.GsonToBean(str, ResultData.class);
                if (baseData.getData() == null || "null".equals(baseData.getData().toString())) {
                    ApiException apiException = new ApiException(new Throwable(baseData.getMsg()), baseData.getCode());
//                    Toast.makeText(context,baseData.getMsg(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    switch (baseData.getCode()) {
                        case 20000://账户不存在
                            DataManager.getUserInfo().setSyncState(false);
                            break;
                        case 210003://账户不存在
                            DataManager.getUserInfo().setSyncState(false);
                            break;
                    }
                    return;
                }
                switch (baseData.getCode()) {
                    case 200:
                        httpManagerCallback.onSuccess(baseData);
                        break;
                    case 210003://账户不存在
                        httpManagerCallback.onSuccess(baseData);
                        break;
                }
            }
        });
    }

    /**
     * POST请求
     *
     * @param url
     * @param params
     */
    public synchronized Disposable post(final String url, HttpParams params) {
        if (!NetUtil.hasNet(MyApplication.mContext)) {
            ToastUtils.showShort(MyApplication.mContext.getResources().getString(R.string.toast_no_net));
            ApiException apiException = new ApiException(new Throwable("无网络"), -100);
            httpManagerCallback.onError(apiException);
            return null;
        }

        final CustomPostRequest customPostRequest = new CustomPostRequest(url);

        JSONObject jsonObject = new JSONObject(params.urlParamsMap);

        if (DataManager.getUserInfo() == null) {
            restartApplication(context);
            return null;
        }
        String privateKey = null;
        try {
            privateKey = AESCrypt.decrypt(DataManager.getUserInfo().getSaftyCode(), DataManager.getUserInfo().getCompressedPrivkey());
        } catch (GeneralSecurityException e) {
            restartApplication(context);
        }

        HttpHeaders httpHeaders = getHeaders();

        String js = jsonObject.toString();
//        LogUtil.error("ramon", "jsonstr: " +js );

        String originalBody = js + Constants.getSTAMP_KEY() + httpHeaders.get("timestamp");
        LogUtil.error("ramon", "body: " + originalBody);
        String bitcoinJBody = "";
        if (!TextUtils.isEmpty(originalBody) && !TextUtils.isEmpty(privateKey)) {
            bitcoinJBody = BitcoinjUtils.signMsg(originalBody, privateKey).replace(" ", "").trim();
        }
        httpHeaders.put("signAsStr", bitcoinJBody);
        httpHeaders.put("contentbody", js);
        customPostRequest.headers(httpHeaders);

        LogUtil.info(LOG_TAG, httpHeaders.toJSONString());

//        boolean bitcoinPub = BitcoinjUtils.verifyMessage(originalBody, bitcoinJBody,DataManager.getUserInfo().getCompressedPubkey());
//        Log.d(LOG_TAG,"私钥:"+privateKey+"公钥:"+DataManager.getUserInfo().getCompressedPubkey()+"加密前:"+originalBody+"加密后:"+bitcoinJBody+"是否验证成功："+bitcoinPub);
        RequestBody requestBody = FormBody.create(MediaType.parse("text/plain"), js);
        customPostRequest.requestBody(requestBody);
        if (baseUrl != null) {
            customPostRequest.baseUrl(baseUrl);
        } else {
            customPostRequest.baseUrl(APIConstant.getBASE_URL());
        }
        //此框架类型被擦除
        return customPostRequest.execute(new CallBack<String>() {

            @Override
            public void onStart() {
                httpManagerCallback.onStart();
            }

            @Override
            public void onCompleted() {
                httpManagerCallback.onCompleted();
                httpManagerCallback.onResp();
            }

            @Override
            public void onError(ApiException e) {
                httpManagerCallback.onResp();
                LogUtil.info("wase", e.getMessage() + "<<ApiException");
                if (context != null) {
//                    Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                httpManagerCallback.onError(e);
            }

            @Override
            public void onSuccess(String str) {
                httpManagerCallback.onResp();
                LogUtil.info("wase", str + "<<http");
                if (str == null || "".equals(str)) {
                    ApiException apiException = new ApiException(new Throwable("返回数据为null"), -100);
//                    Toast.makeText(context,apiException.getMessage(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    return;
                }
                ResultData baseData = GsonUtil.GsonToBean(str, ResultData.class);
                if (baseData.getData() == null || "null".equals(baseData.getData().toString())) {
                    ApiException apiException = new ApiException(new Throwable(baseData.getMsg()), baseData.getCode());
//                    Toast.makeText(context,baseData.getMsg(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    switch (baseData.getCode()) {
                        case 20000://账户不存在
                            DataManager.getUserInfo().setSyncState(false);
                            break;
                        case 210003://账户不存在
                            DataManager.getUserInfo().setSyncState(false);
                            break;
                    }
                    return;
                }
                switch (baseData.getCode()) {
                    case 200:
                        httpManagerCallback.onSuccess(baseData);
                        break;
                    case 210003://账户不存在
                        httpManagerCallback.onSuccess(baseData);
                        break;
                }
            }
        });
    }

    /**
     * GET请求
     *
     * @param url
     * @param params
     */
    public void get(final String url, HttpParams params) {
        final CustomGetRequest customGetRequest = new CustomGetRequest(url);
        if (baseUrl != null) {
            customGetRequest.baseUrl(baseUrl);
        } else {
            customGetRequest.baseUrl(APIConstant.getBASE_URL());
        }
        customGetRequest.params(params);
        //此框架类型被擦除
        customGetRequest.execute(new CallBack<String>() {

            @Override
            public void onStart() {
                httpManagerCallback.onStart();
            }

            @Override
            public void onCompleted() {
                httpManagerCallback.onCompleted();
            }

            @Override
            public void onError(ApiException e) {
                if (context != null) {
                    Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                httpManagerCallback.onError(e);
            }

            @Override
            public void onSuccess(String str) {
                if (str == null || "".equals(str)) {
                    ApiException apiException = new ApiException(new Throwable("返回数据为null"), -100);
                    Toast.makeText(context, apiException.getMessage(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    return;
                }
                ResultData baseData = GsonUtil.GsonToBean(str, ResultData.class);
                if (baseData.getData() == null || "null".equals(baseData.getData().toString())) {
                    ApiException apiException = new ApiException(new Throwable(baseData.getMsg()), baseData.getCode());
                    Toast.makeText(context, baseData.getMsg(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    return;
                }
                switch (baseData.getCode()) {
                    case 200:
                        httpManagerCallback.onSuccess(baseData);
                        break;
                }
            }
        });
    }

    /**
     * Description:MD5工具生成token
     *
     * @param value
     * @return
     */
    public static String getMD5Value(String value) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] md5ValueByteArray = messageDigest.digest(value.getBytes());
            BigInteger bigInteger = new BigInteger(1, md5ValueByteArray);
            return bigInteger.toString(16).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static HttpParams getCustomParams(Context context) {
        HttpParams httpParams = new HttpParams();
        httpParams.put("timeStamp", String.valueOf(System.currentTimeMillis()));
        httpParams.put("os", "android");

        return httpParams;
    }

    /**
     * 上传 文件
     *
     * @param file
     */
    public void uploadFile(File file) {

        HttpParams params = new HttpParams();
        final CustomPostRequest customPostRequest = new CustomPostRequest(APIConstant.UPLOAD_FILE);
        JSONObject jsonObject = new JSONObject(params.urlParamsMap);
        if (DataManager.getUserInfo() == null) {
            restartApplication(context);
            return;
        }
        if (DataManager.getUserInfo() == null) {
            restartApplication(context);
            return;
        }
        String privateKey = null;
        try {
            privateKey = AESCrypt.decrypt(DataManager.getUserInfo().getSaftyCode(), DataManager.getUserInfo().getCompressedPrivkey());
        } catch (GeneralSecurityException e) {
            restartApplication(context);
        }

        HttpHeaders httpHeaders = getHeaders();
        String originalBody = jsonObject.toString() + Constants.getSTAMP_KEY() + httpHeaders.get("timestamp");
        String bitcoinJBody = BitcoinjUtils.signMsg(originalBody, privateKey).replace(" ", "").trim();
        httpHeaders.put("signAsStr", bitcoinJBody);
        customPostRequest.headers(httpHeaders);
        LogUtil.info(LOG_TAG, httpHeaders.toJSONString());

//        boolean bitcoinPub = BitcoinjUtils.verifyMessage(originalBody, bitcoinJBody,DataManager.getUserInfo().getCompressedPubkey());
//        Log.d(LOG_TAG,"私钥:"+privateKey+"公钥:"+DataManager.getUserInfo().getCompressedPubkey()+"加密前:"+originalBody+"加密后:"+bitcoinJBody+"是否验证成功："+bitcoinPub);
        Log.e("ramon", "文件大小： " + file.length());
        RequestBody requestBody = FormBody.create(MediaType.parse("image/*"), file);

//        customPostRequest.requestBody(requestBody);
        customPostRequest.params("file", file, new ProgressResponseCallBack() {
            @Override
            public void onResponseProgress(long bytesWritten, long contentLength, boolean done) {

            }
        });

        if (baseUrl != null) {
            customPostRequest.baseUrl(baseUrl);
        } else {
            customPostRequest.baseUrl(APIConstant.getBASE_URL());
        }
        //此框架类型被擦除
        customPostRequest.execute(new CallBack<String>() {

            @Override
            public void onStart() {
                httpManagerCallback.onStart();
            }

            @Override
            public void onCompleted() {
                httpManagerCallback.onCompleted();
                httpManagerCallback.onResp();
            }

            @Override
            public void onError(ApiException e) {
                httpManagerCallback.onResp();
                LogUtil.info("wase", e.getMessage() + "<<ApiException");
                if (context != null) {
//                    Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                httpManagerCallback.onError(e);
            }

            @Override
            public void onSuccess(String str) {
                httpManagerCallback.onResp();
                LogUtil.info("wase", str + "<<http");
                if (str == null || "".equals(str)) {
                    ApiException apiException = new ApiException(new Throwable("返回数据为null"), -100);
//                    Toast.makeText(context,apiException.getMessage(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    return;
                }
                ResultData baseData = GsonUtil.GsonToBean(str, ResultData.class);
                if (baseData.getData() == null || "null".equals(baseData.getData().toString())) {
                    ApiException apiException = new ApiException(new Throwable(baseData.getMsg()), baseData.getCode());
//                    Toast.makeText(context,baseData.getMsg(), Toast.LENGTH_SHORT).show();
                    httpManagerCallback.onError(apiException);
                    switch (baseData.getCode()) {
                        case 20000://账户不存在
                            DataManager.getUserInfo().setSyncState(false);
                            break;
                        case 210003://账户不存在
                            DataManager.getUserInfo().setSyncState(false);
                            break;
                    }
                    return;
                }
                switch (baseData.getCode()) {
                    case 200:
                        httpManagerCallback.onSuccess(baseData);
                        break;
                    case 210003://账户不存在
                        httpManagerCallback.onSuccess(baseData);
                        break;
                }
            }
        });

    }
}